import tkinter as tk
import constants as const
from card import Card
from eventcenter import eventcenter as et
from datacenter import datacenter as dc

class MidPanel(tk.Frame):
    """中间面板类，负责显示和管理卡片的画布"""
    def __init__(self, root):
        """初始化中间面板
        
        Args:
            root: 父窗口对象
        """
        super().__init__(root)
        self.root = root
        self.grid(row=0, column=1, sticky="nsew")

        self.canvas = None
        self.cards = []
        self.drag_data = {"x": 0, "y": 0, "item": None}
        self.current_selected_card = None
        self.is_hide = False

        self._init_event()
        self._create_widgets()

        # 延时等待窗口大小调整完成后再初始化画布
        self.after(100, self._init_canvas)
        
    def _init_event(self):
        """初始化事件监听"""
        et.add_event(const.event_on_new_card, self._event_on_new_card)
        et.add_event(const.event_on_del_card, self._event_on_del_card) 
        et.add_event(const.event_guide_menu_cliciked, self._event_guide_menu_clicked)
        et.add_event(const.event_card_value_changed, self._event_card_value_changed)
        et.add_event(const.event_reset_all, self._event_reset_all)

    def _create_widgets(self):
        """创建界面组件"""
        # 创建工具栏
        self.toolbar = tk.Frame(self, bg=const.canvas_bg_color)
        self.toolbar.pack(side=tk.TOP, fill=tk.BOTH)

        self.show_hide_btn = tk.Button(self.toolbar, text="隐藏", command=self._tool_hide)
        self.show_hide_btn.pack(side=tk.RIGHT)
        
    def _init_canvas(self):
        """初始化画布"""
        width = self.winfo_width()
        height = self.winfo_height()

        if not self.canvas:
            self.canvas = tk.Canvas(
                self,
                width=width,
                height=height,
                bg=const.canvas_bg_color,
            )
            self.canvas.pack(expand=True, anchor=tk.CENTER)
        else:
            self.canvas.delete("all")

        # 绑定鼠标事件
        self.canvas.tag_bind("all", "<ButtonPress-1>", self._on_drag_start)
        self.canvas.tag_bind("all", "<B1-Motion>", self._on_drag_motion)
        # self.canvas.tag_bind("all", "<Double-Button-1>", self._on_double_click)

        self._draw_game_frame()

    def _draw_game_frame(self):
        """绘制游戏边框"""
        rect_x2 = const.game_window_width - const.fix_distance
        rect_y2 = const.game_window_height - const.fix_distance
        self.canvas.create_rectangle(const.fix_distance, const.fix_distance, 
                                     rect_x2, rect_y2, outline="black", width=2)
        
        # 计算矩形中心点坐标
        center_x = (const.fix_distance + rect_x2) / 2
        center_y = (const.fix_distance + rect_y2) / 2
        
        # 在中心点绘制一个红色圆点
        dot_radius = 3
        self.canvas.create_oval(center_x - dot_radius, center_y - dot_radius,
                               center_x + dot_radius, center_y + dot_radius,
                               fill="red", outline="red")

    def _on_drag_start(self, event):
        """处理拖动开始事件
        
        Args:
            event: 鼠标事件对象
        """
        item = event.widget.find_closest(event.x, event.y)
        tags = event.widget.gettags(item)
        if tags:
            card_tag = tags[0]
            selected_card = next(
                (card for card in self.cards if card.get_tag() == card_tag),
                None
            )

            if selected_card:
                self._select_card(selected_card, False, True)
                dc.curmap.make_ver_change()
            
            # 更新拖动数据
            self.drag_data["item"] = selected_card
            self.drag_data["x"] = event.x
            self.drag_data["y"] = event.y
    
    def _select_card(self, selected_card, cancel=False, send_event=False):
        """选择卡片
        
        Args:
            selected_card: 要选择的卡片对象
            cancel: 是否取消选择
            send_event: 是否发送事件
        """
        if selected_card:
            # 取消之前选中的牌
            if self.current_selected_card and self.current_selected_card != selected_card:
                self.current_selected_card.deselect()
            
            # 切换当前牌的选中状态
            if selected_card.is_selected:
                if not cancel:
                    return
                selected_card.deselect()
                self.current_selected_card = None
                et.dispatch_event(const.event_select_card, selected_card.data.uid, False)
            else:
                selected_card.select()
                self.current_selected_card = selected_card
                et.dispatch_event(const.event_select_card, selected_card.data.uid, True)

    def _on_drag_motion(self, event):
        """处理拖动移动事件，限制卡片不能超出边界
        
        Args:
            event: 鼠标事件对象
        """
        selected_card = self.drag_data["item"]
        if selected_card:
            dx = event.x - self.drag_data["x"]
            dy = event.y - self.drag_data["y"]

            px = selected_card.data.x
            py = selected_card.data.y

            # 限制拖动范围
            if px + dx < const.fix_distance:
                dx = -px + const.fix_distance
            elif px + dx > const.game_window_width - const.card_width - const.fix_distance:
                dx = const.game_window_width - const.card_width - px - const.fix_distance
            if py + dy < const.fix_distance:
                dy = -py + const.fix_distance
            elif py + dy > const.game_window_height - const.card_height - const.fix_distance:
                dy = const.game_window_height - const.card_height - py - const.fix_distance

            selected_card.move(dx, dy)
            self.drag_data["x"] = event.x
            self.drag_data["y"] = event.y

            # 传递移动后的位置
            et.dispatch_event(const.event_select_card_move, selected_card.data.uid, px + dx, py + dy)

    def _on_double_click(self, event):
        """处理双击翻转事件
        
        Args:
            event: 鼠标事件对象
        """
        item = event.widget.find_closest(event.x, event.y)
        tags = event.widget.gettags(item)
        if tags:
            card_tag = tags[0]
            selected_card = next(
                (card for card in self.cards if card.get_tag() == card_tag),
                None
            )
            if selected_card:
                selected_card.flip()
                selected_card.deselect()

    def _add_new_card(self, uid):
        """添加新卡片
        
        Args:
            uid: 卡片唯一标识
        """
        data = dc.get_card(uid)
        if data:
            card = Card(self.canvas, data)
            self.cards.append(card)

    def _del_card_ui(self, uids):
        """仅删除卡片UI
        
        Args:
            uid: 卡片唯一标识
        """
        for uid in uids:
            card = next(
                (card for card in self.cards if card.data.uid == uid),
                None
            )
            if card:
                card.clear_graphics()
                self.cards.remove(card)
        

    def _tool_hide(self):
        """隐藏工具按钮处理函数"""
        self.is_hide = not self.is_hide
        
        # 修复：检查current_selected_card是否为None
        if self.is_hide:
            if self.current_selected_card is None:
                return
            layerid = self.current_selected_card.data.layerid
        else:
            layerid = len(dc.curmap.cuids)

        if layerid < 0: 
            return

        self.show_hide_btn.config(text=f"显示 层级>{layerid}" if self.is_hide else "隐藏")
       
        for card in self.cards:
            if card.data.layerid > layerid:
                if card.is_show:
                    card.clear_graphics()
            else:
                if not card.is_show:
                    card.draw_card()

    def _tool_refresh(self):
        """刷新工具按钮处理函数"""
        self._adjust_card_layers()

    def _adjust_card_layers(self):
        """调整卡片层级"""
        # 获取优先级列表，优先级高的在前面
        priority_list = dc.curmap.get_draw_list()

        for uid in priority_list:
            card = next((card for card in self.cards if card.data.uid == uid), None)
            if card:
                self.canvas.tag_raise(card.get_tag())

    def _event_on_new_card(self, uid, layer, index):
        """新卡片事件处理
        
        Args:
            uid: 卡片唯一标识
            layer: 层级
            index: 索引
        """
        self._add_new_card(uid)
        self._adjust_card_layers()

    def _event_on_del_card(self, uid):
        """删除卡片事件处理
        
        Args:
            uid: 卡片唯一标识
            layer: 层级
            index: 索引
        """
        if type(uid) is not list:
            self._del_card_ui([uid])
            return
        
        self._del_card_ui(uid)

    def _event_guide_menu_clicked(self, uid, layerid, index):
        """导航菜单点击事件处理
        
        Args:
            uid: 卡片唯一标识
            layerid: 层级ID
            index: 索引
        """
        ls = [v for v in self.cards if v.data.uid == uid]
        if len(ls) == 1:
            self._select_card(ls[0], True, True)

    def _event_card_value_changed(self, uid, refreshall = False):
        """卡片值变更事件处理
        
        Args:
            uid: 卡片唯一标识
        """
        ls = [v for v in self.cards if v.data.uid == uid]
        if len(ls) == 1:
            ls[0].draw_card()
            self._adjust_card_layers()
    
    def _event_reset_all(self):
        """重置所有事件处理"""
        self.cards.clear()
        self.canvas.delete("all")
        self._draw_game_frame()

        priority_list = dc.curmap.get_draw_list()
        for uid in priority_list:
            self._add_new_card(uid)
        